
//  Copyright (c) Microsoft Corporation.  All Rights Reserved.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.ServiceModel.Samples.XmlRpc;
using System.Xml;
using System.IO;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.ServiceModel;

namespace Microsoft.ServiceModel.Samples.XmlRpc.Test
{
    class Program
    {
        [DataContract]
        public class SimpleClass1
        {
            [DataMember]
            private int a;
            [DataMember(Name="foobar")]
            public double b;
            [DataMember]
            internal DateTime c;
            
            private string _p;
            [DataMember]
            public string P
            {
                get { return _p; }
                set { _p = value; }
            }

            private string _q;
            [DataMember]
            private string Q
            {
                get { return _q; }
                set { _q = value; }
            }
	

            public SimpleClass1()
            {
            }

            public SimpleClass1(bool init)
            {
                if (init) Init();
            }

            public void Init()
            {
                b = 2;
                c = DateTime.Now;
                _p = "test";
                _q = "tset";
            }
        }

        [DataContract]
        public class SimpleClass2
        {
            [DataMember]
            private int a;
            [DataMember(Name = "foobar")]
            public double b;
            [DataMember]
            internal DateTime c;
            [DataMember]
            private SimpleClass1 d;

            public SimpleClass2()
            {
            }

            public SimpleClass2(bool init)
            {
                if (init) Init();
            }

            public void Init()
            {
                b = 2;
                c = DateTime.Now;
                d = new SimpleClass1(true);
            }
        }

        [ServiceContract]
        public interface ISimpleService
        {
            [OperationContract(Action="mt.FooBar")]
            string SimpleCall(string a, string b);
        }

        static void TestSerialize<T>(params T[] values )
        {
            Console.WriteLine("Serializing {0}:", typeof(T).Name);
            using ( Stream stdout = Console.OpenStandardOutput() )
            {
                XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(stdout);
                foreach (T value in values)
                {
                    XmlRpcDataContractSerializationHelper.Serialize(writer, value);
                    writer.WriteWhitespace("\n");
                }
                writer.Close();
            }
            Console.WriteLine("------");
        }

        static void TestSerializeDeserialize<T>(params T[] values)
        {
            Console.WriteLine("Serializing/Deserializing {0}:", typeof(T).Name);
            foreach (T value in values)
            {
                using (MemoryStream memStream = new MemoryStream())
                {

                    XmlDictionaryWriter writer = XmlDictionaryWriter.CreateTextWriter(memStream);
                    XmlRpcDataContractSerializationHelper.Serialize(writer, value);
                    writer.Flush();

                    memStream.Position = 0;

                    XmlDictionaryReaderQuotas quotas = new XmlDictionaryReaderQuotas();
                    XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(memStream, quotas);
                    T result = (T)XmlRpcDataContractSerializationHelper.Deserialize(reader, typeof(T));
                    reader.Close();

                    if (typeof(T).IsValueType)
                    {
                        Debug.Assert(result.Equals(value), "Result not equal to value");
                    }
                }
            }

        }

        static void Main(string[] args)
        {
            TestSerialize<int>(int.MinValue,-1,0,1,int.MaxValue);
            TestSerialize<string>("", "abcdefghijklmnopqrstuvwxyz");
            TestSerialize<DateTime>(DateTime.MinValue, DateTime.Now, DateTime.MaxValue);
            TestSerialize<double>(double.MinValue, -Math.PI, -1.1111d, -1.1d, 0d, 1.1d, 1.1111d, Math.PI, double.MaxValue);
            TestSerialize<bool>(true, false);
            TestSerialize<byte[]>(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
            TestSerialize<string[]>(new string[] { "", "1", "22", "33" });
            TestSerialize<SimpleClass1>(new SimpleClass1(true));
            TestSerialize<SimpleClass2>(new SimpleClass2(true));

            TestSerializeDeserialize<int>(int.MinValue, -1, 0, 1, int.MaxValue);
            TestSerializeDeserialize<string>("", "abcdefghijklmnopqrstuvwxyz");
            TestSerializeDeserialize<DateTime>(DateTime.MinValue, DateTime.Now, DateTime.MaxValue);
            TestSerializeDeserialize<double>(double.MinValue, -Math.PI, -1.1111d, -1.1d, 0d, 1.1d, 1.1111d, Math.PI, double.MaxValue);
            TestSerializeDeserialize<bool>(true, false);
            TestSerializeDeserialize<byte[]>(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
            TestSerializeDeserialize<string[]>(new string[] { "", "1", "22", "33" });
            TestSerializeDeserialize<SimpleClass1>(new SimpleClass1(true));
            TestSerializeDeserialize<SimpleClass2>(new SimpleClass2(true));


            XmlRpcServiceHost serviceHost = new XmlRpcServiceHost(typeof(BloggerAPI));
            serviceHost.Open();
                        
            XmlRpcChannelFactory<IBloggerAPI> client = new XmlRpcChannelFactory<IBloggerAPI>(new XmlRpcHttpBinding(), new EndpointAddress("http://localhost/samples/blogger"));
            IBloggerAPI blogger = client.CreateChannel();
            Microsoft.ServiceModel.Samples.XmlRpc.Contracts.MetaWeblog.Post post = new Microsoft.ServiceModel.Samples.XmlRpc.Contracts.MetaWeblog.Post();
            post.dateCreated = DateTime.Now;
            post.description = "foo";
            post.title = "title";
            string s = blogger.metaweblog_newPost("1", "user", "pass", post, true);
            Console.WriteLine(s);

            Console.WriteLine("Blogger API endpoint listening at http://localhost/samples/blogger");
            Console.WriteLine("Perform manual test with your favorite metaWeblog blogging tool (e.g. Word 2007)");
            Console.Write("Press ENTER to quit");
            Console.ReadLine();

            serviceHost.Close();

            
            
        }
    }
}
